#include "include.h"
#include "api.h"

#if HUART_EN

void sco_huart_tx_done(void);
void set_vusb_uart_flag(u8 flag);

AT(.com_huart.text)
void huart_tx_done(void)
{
//    sco_huart_tx_done();
}

AT(.com_huart.text)
void huart_rx_done(void)
{
    if(huart_rx_buf[0] == 0xF5 && huart_rx_buf[1] == 0xA0 && huart_rx_buf[2] == 0xA5 && huart_rx_buf[3] == 0x96 && huart_rx_buf[4] == 0x87 && huart_rx_buf[5] == 0x5A){
		WDT_RST();
		while(1);
	}

#if EQ_DBG_IN_UART
    if(bsp_eq_rx_done(huart_rx_buf)){
        return;
    }
#endif
//
//#if IODM_TEST_MODE
//    bsp_iodm_packet_dma_recv(huart_rx_buf);
//#endif
}

void bsp_huart_init(void)
{
    u32 baud_rate = 1500000;
#if IODM_TEST_MODE_HUART_EN
        baud_rate = 9600;
#endif
    if (xcfg_cb.huart_sel == 0) {
        if (UART0_PRINTF_SEL == PRINTF_PA7) {
            FUNCMCON0 = 0x0f << 8;
        }
    }else if (xcfg_cb.huart_sel == 2) {
        if (UART0_PRINTF_SEL == PRINTF_PB3) {
            FUNCMCON0 = 0x0f << 8;
        }

    }
    if((xcfg_cb.huart_sel == 10)){
         if(!sys_cb.vusb_uart_flag){
            FUNCMCON0 = 11 << 20 | 11 << 16;
            PWRCON0 |= BIT(30);                             //Enable VUSB GPIO
            RTCCON &= ~BIT(6);                              //关充电复位
#if VUSB_SMART_VBAT_HOUSE_EN||VUSB_TBOX_QTEST_EN || IODM_TEST_MODE
            baud_rate = 9600;
#endif
            xcfg_cb.chg_inbox_pwrdwn_en=0;                  //入仓耳机关机
            set_vusb_uart_flag(1);
         }else{
             return;
         }
    }
    memset(eq_rx_buf, 0, EQ_BUFFER_LEN);
    huart_init_do(xcfg_cb.huart_sel, xcfg_cb.huart_sel, baud_rate, eq_rx_buf, EQ_BUFFER_LEN,1);
}
#else
void bsp_huart_init(void) {}
#endif

u8* huart_get_rxbuf(u16 *len)
{
    *len  = EQ_BUFFER_LEN;
    return eq_rx_buf;
}

#define UART_EXAMPLE_EN         0
#define HALF_DUPLEX_UART_PA7    1   //PA7半双工通信(UART1)
#define HALF_DUPLEX_UART_PB2    1   //PB2半双工通信(UART2)
#if UART_EXAMPLE_EN

#define UART1_FIFO_BUFFER_SIZE        96//64//32
uchar uart1_PutPtr;
uchar uart1_GetPtr;
uchar  uart1_fifo[UART1_FIFO_BUFFER_SIZE];

#define UART2_FIFO_BUFFER_SIZE        96//64//32
uchar uart2_PutPtr;
uchar uart2_GetPtr;
uchar  uart2_fifo[UART2_FIFO_BUFFER_SIZE];

typedef void (*isr_t)(void);
isr_t register_isr(int vector, isr_t isr);
u32 get_sysclk_nhz(void);

///中断处理函数
AT(.com_text.uart)
void uart_isr_func(void)
{
	uchar idx_1;
	uchar idx_2;
    if(UART1CON & BIT(9)){  //RX one byte finish
        UART1CPND |= BIT(9);    //clear pending
      	 idx_1 = uart1_PutPtr;
	  	 uart1_fifo[idx_1] = UART1DATA;
		 ++idx_1;
		 if(idx_1 == UART1_FIFO_BUFFER_SIZE) idx_1 = 0x0;
	//	 if(idx_1 != uart1_GetPtr)
		 {
		 	uart1_PutPtr = idx_1;
		 }
     }

    if(UART2CON & BIT(9)){ //RX one byte finish
        UART2CPND |= BIT(9);    //clear pending
      	 idx_2 = uart2_PutPtr;
	  	 uart2_fifo[idx_2] = UART2DATA;
		 ++idx_2;
		 if(idx_2 == UART2_FIFO_BUFFER_SIZE) idx_2 = 0x0;
	//	 if(idx_2 != uart1_GetPtr)
		 {
		 	uart2_PutPtr = idx_2;
		 }
     }
}

///UART1 buf的初始化
void uart1_fifoinit(void)
{
   uart1_PutPtr = uart1_GetPtr = 0;
}

///UART1检测buf是否为空
AT(.com_text.detect)
uchar uart1_fifoisempty(void)
{
   if (uart1_PutPtr == uart1_GetPtr){
      return(1);                        // Empty if uart1_PutPtr = uart1_GetPtr
   }else{
      return(0);
   }
}

///UART1得到buf数据
AT(.com_text.detect)
uchar uart1_fifoget(void)
{
   uchar c;

   if (uart1_PutPtr == uart1_GetPtr){
      return(0);                // Empty if uart1_PutPtr = uart1_GetPtr
   }else{
      c = uart1_fifo[uart1_GetPtr];
      ++uart1_GetPtr;
      if (uart1_GetPtr == UART1_FIFO_BUFFER_SIZE) uart1_GetPtr = 0;
      return(c);
   }
}
///UART1发送数据
void uart1_puts(uchar *cmd,uchar len)
{
    #if HALF_DUPLEX_UART_PA7
    GPIOADIR &= ~BIT(7);
    #endif // HALF_DUPLEX_UART_PA7
	uchar i;
	for(i=0;i<len;i++){
		while (!(UART1CON & BIT(8)));
		UART1DATA = *(cmd+i);

	}
	#if HALF_DUPLEX_UART_PA7
	while (!(UART1CON & BIT(8)));
	GPIOADIR |= BIT(7);
	#endif // HALF_DUPLEX_UART_PA7
//	printf("send finish\n");
}

///UART1发指令接口 长度暂定为1byte
void uart1_puts_cmd(u8 msg_user)
{
    static u8 tx_buf[5]= {0,};
//    memset(tx_buf,0x01,5);
//    uart1_puts(tx_buf,5);
    tx_buf[0] = msg_user;
    uart1_puts(tx_buf,1);
}

///UART1配置初始化
void uart1_init(u32 baudrate)
{
    #if !HALF_DUPLEX_UART_PA7
    printf("uart1_init\n");

    GPIOAFEN |= (BIT(3) | BIT(4));
    GPIOADIR &= ~BIT(4);
    GPIOADIR |= BIT(3);
    GPIOAPU  |= BIT(3);
    GPIOADE  |= (BIT(3) | BIT(4));
    FUNCMCON0 |= ((0xFL << 28) | (0xFL << 24));
    FUNCMCON0 |= (0x2L << 28) | (0x2L << 24);

    UART1CON = 0;

    UART1CON &= ~BIT(5);
    CLKGAT0 |= BIT(21);
    u32 uart1_baud = ((get_sysclk_nhz() + (baudrate / 2)) / baudrate) - 1;

    //UART1CON |= BIT(5);      //uart_clk sel uart_inc
    //CLKCON1 |= BIT(14);
    //u32 uart2_baud =  (26000000/2 + baudrate/2)/baudrate-1 ;

    UART1BAUD = (uart1_baud << 16) | uart1_baud; //UARTBAUD = Fsys_clock/BaudRate-1  //UARTBAUD= (26000000/2)/baud-1 //16~31 rx_baud  0~15 tx_baud
    UART1CON |= (BIT(7) | BIT(2) | BIT(0)); // BIT(7)RX en，BIT(2)RX INT en，BIT(0)uart en

    register_isr(IRQ_UART_VECTOR, uart_isr_func);
    PICPR &= ~BIT(IRQ_UART_VECTOR);
    PICEN |= BIT(IRQ_UART_VECTOR);
    uart1_fifoinit();
    #endif
    #if HALF_DUPLEX_UART_PA7
    //PA7 半双工通信 串口1 配置
    printf("uart1_init PA7 RX&TX\n");
    GPIOAFEN |= ( BIT(7));
//    GPIOADIR &= ~BIT(7);
    GPIOADIR |= BIT(7);
    GPIOADE  |= (BIT(7));

    CLKGAT0 |= BIT(21);
    FUNCMCON0 |= ((0xFL << 28) | (0xFL << 24));
    FUNCMCON0 |= (0x3L << 28) | (0x1L << 24);

    UART1CON = 0;
    UART1CON &= ~BIT(5);

    u32 uart1_baud = ((get_sysclk_nhz() + (baudrate / 2)) / baudrate) - 1;
    UART1BAUD = (uart1_baud << 16) | uart1_baud; //UARTBAUD = Fsys_clock/BaudRate-1  //UARTBAUD= (26000000/2)/baud-1 //16~31 rx_baud  0~15 tx_baud
    UART1CON |= (BIT(7) | BIT(2) | BIT(0));

    register_isr(IRQ_UART_VECTOR, uart_isr_func);
    PICPR &= ~BIT(IRQ_UART_VECTOR);
    PICEN |= BIT(IRQ_UART_VECTOR);
    uart1_fifoinit();
    #endif
}

#if HALF_DUPLEX_UART_PA7
#define UART1_MSG_WARNING   0xA1
volatile u8 change_flag = 1;
//添加至主线程大循环调用处理
AT(.text.func.process)
void half_duplex_uart_pa7_rx_process(void)
{
    u8 tx_buf[3]= {0xFF,0xFF,0xFF};
    u8 rx_msg = 0;
    static u32 ticks = 0;
    if (tick_check_expire(ticks,1000)) {
        ticks = tick_get();
        ///TX 数据数据参考示例
        uart1_puts(tx_buf,3);

        ///RX 数据处理参考示例
        rx_msg = uart1_fifoget();
        //printf("rx %x\r\n",rx_msg);
        if(!rx_msg)return;
        switch(rx_msg)
        {
            case UART1_MSG_WARNING:

                break;
            default:
                //printf("MSG ERR\n");
                break;
        }

    }
}
#endif
/******************************************/
///UART2 buf的初始化
void uart2_fifoinit(void)
{
   uart2_PutPtr = uart2_GetPtr = 0;
}

///UART2检测buf是否为空
uchar uart2_fifoisempty(void)
{
   if (uart2_PutPtr == uart2_GetPtr){
      return(1);                        // Empty if uart1_PutPtr = uart1_GetPtr
   }
   else{
      return(0);
   }
}

///UART2得到buf数据
uchar uart2_fifoget(void)
{
   uchar c;

   if (uart2_PutPtr == uart2_GetPtr){
      return(0);                // Empty if uart1_PutPtr = uart1_GetPtr
   }
   else{
      c = uart2_fifo[uart2_GetPtr];
      ++uart2_GetPtr;
      if (uart2_GetPtr == UART2_FIFO_BUFFER_SIZE) uart2_GetPtr = 0;
      return(c);
   }
}

///UART1发送数据
void uart2_puts(uchar *cmd, uchar len)
{
    #if HALF_DUPLEX_UART_PB2
    GPIOBDIR &= ~BIT(2);
    #endif // HALF_DUPLEX_UART_PA7
	uchar i;
	for(i=0;i<len;i++){
		while (!(UART2CON & BIT(8)));
		UART2DATA = *(cmd+i);
	}
//	printf("send finish\n");

	#if HALF_DUPLEX_UART_PB2
	while (!(UART2CON & BIT(8)));
	GPIOBDIR |= BIT(2);
	#endif // HALF_DUPLEX_UART_PB
}

///UART2配置初始化
void uart2_init(u32 baudrate)
{
    printf("uart2_init\n");
#if HALF_DUPLEX_UART_PB2

	  GPIOBFEN |= (BIT(2));
	  GPIOBDIR &= ~BIT(2);
	  GPIOBDE  |= (BIT(2));

	  FUNCMCON1 |= ((0xFL << 8) | (0xFL << 4));
	  FUNCMCON1 |= (0x3L << 8) | (0x2L << 4);

	  UART2CON = 0;

	  UART2CON &= ~BIT(5);
	  CLKGAT1 |= BIT(11);
      u32 uart2_baud = ((get_sysclk_nhz() + (baudrate / 2)) / baudrate) - 1;

      UART2BAUD = (uart2_baud << 16) | uart2_baud; //UARTBAUD = Fsys_clock/BaudRate-1  //UARTBAUD= (26000000/2)/baud-1 //16~31 rx_baud  0~15 tx_baud
      UART2CON |= (BIT(7) | BIT(2) | BIT(0)); // BIT(7)RX en，BIT(2)RX INT en，BIT(0)uart en

      register_isr(IRQ_UART_VECTOR, uart_isr_func);
      PICPR &= ~BIT(IRQ_UART_VECTOR);
      PICEN |= BIT(IRQ_UART_VECTOR);

      uart2_fifoinit();
#endif
#if !HALF_DUPLEX_UART_PB2
	  GPIOBFEN |= (BIT(1) | BIT(2));
	  GPIOBDIR &= ~BIT(2);
	  GPIOBDIR |= BIT(1);
	  GPIOBPU  |= BIT(1);
	  GPIOBDE  |= (BIT(1) | BIT(2));
	  FUNCMCON1 |= ((0xFL << 8) | (0xFL << 4));
	  FUNCMCON1 |= (0x2L << 8) | (0x2L << 4);

	  UART2CON = 0;

	  UART2CON &= ~BIT(5);
	  CLKGAT1 |= BIT(11);
      u32 uart2_baud = ((get_sysclk_nhz() + (baudrate / 2)) / baudrate) - 1;

      UART2BAUD = (uart2_baud << 16) | uart2_baud; //UARTBAUD = Fsys_clock/BaudRate-1  //UARTBAUD= (26000000/2)/baud-1 //16~31 rx_baud  0~15 tx_baud
      UART2CON |= (BIT(7) | BIT(2) | BIT(0)); // BIT(7)RX en，BIT(2)RX INT en，BIT(0)uart en

      register_isr(IRQ_UART_VECTOR, uart_isr_func);
      PICPR &= ~BIT(IRQ_UART_VECTOR);
      PICEN |= BIT(IRQ_UART_VECTOR);

      uart2_fifoinit();
#endif
}

#endif // UART_EXAMPLE_EN

#define PRINT_USE_UART1_EN        0
#if PRINT_USE_UART1_EN

AT(.com_text.detect)
void uart1_put(char ch)
{
    while(!(UART1CON & BIT(8)));
    UART1DATA = ch;
}


///UART1配置初始化
void print_uart1()  /// 打印口使用uart1(PA7),空出uart0
{
      printf("uart1_init\n");
	  GPIOAFEN |= BIT(7);
	  GPIOADIR &= ~BIT(7);
	  GPIOADE  |= BIT(7);
	  FUNCMCON0 |= ((0xFL << 28) | (0xFL << 24));
	  FUNCMCON0 |= ((0xFL << 8) | (0xFL << 12));
	  FUNCMCON0 |= (0x1L << 28) | (0x1L << 24);

	  UART1CON = 0;
	  UART0CON = 0;
	  UART1CON &= ~BIT(5);
	  CLKGAT0 |= BIT(21);
      u32 uart1_baud = ((get_sysclk_nhz() + (1500000 / 2)) / 1500000) - 1;

      UART1BAUD = (uart1_baud << 16) | uart1_baud; //UARTBAUD = Fsys_clock/BaudRate-1  //UARTBAUD= (26000000/2)/baud-1 //16~31 rx_baud  0~15 tx_baud
      UART1CON |= (BIT(0)); // BIT(7)RX en，BIT(2)RX INT en，BIT(0)uart en

      my_printf_init(uart1_put);
}
#endif // PRINT_USE_UART1_EN


